package com.ozo.boot.common.database.config;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.ozo.boot.common.base.constant.CommonFieldConstant;
import com.ozo.boot.common.satoken.context.UserLoginHelper;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.util.ClassUtils;

import java.nio.charset.Charset;
import java.time.LocalDateTime;

/**
 * 自定义sql字段填充器，自动填充创建修改相关字段
 *
 * @author qiangesoft
 * @date 2024-04-11
 */
public class CustomMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        Long userId = UserLoginHelper.getUserId();
        fillIfNull(CommonFieldConstant.CREATE_TIME, now, metaObject, true);
        fillIfNull(CommonFieldConstant.UPDATE_TIME, now, metaObject, true);
        fillIfNull(CommonFieldConstant.CREATE_USER, userId, metaObject, false);
        fillIfNull(CommonFieldConstant.UPDATE_USER, userId, metaObject, false);
        fillIfNull(CommonFieldConstant.DEL_FLAG, false, metaObject, false);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        fillIfNull(CommonFieldConstant.UPDATE_TIME, LocalDateTime.now(), metaObject, true);
        fillIfNull(CommonFieldConstant.UPDATE_USER, UserLoginHelper.getUserId(), metaObject, false);
    }

    /**
     * 为空时填充
     *
     * @param fieldName
     * @param value
     * @param metaObject
     * @param isCover
     */
    private static void fillIfNull(String fieldName, Object value, MetaObject metaObject, boolean isCover) {
        if (value == null) {
            return;
        }
        if (metaObject.hasSetter(fieldName)) {
            Object oldValue = metaObject.getValue(fieldName);
            String oldValueStr = StrUtil.str(oldValue, Charset.defaultCharset());
            if (!StrUtil.isNotBlank(oldValueStr) || isCover) {
                Class<?> getterType = metaObject.getGetterType(fieldName);
                if (ClassUtils.isAssignableValue(getterType, value)) {
                    metaObject.setValue(fieldName, value);
                }
            }
        }
    }
}
